package main

import (
	"fmt"
	"log"
	"net"
	"net/rpc"

	// gitee.com/go-course/go12/skills 命名空间 + 目录结果 rpc/service
	"gitee.com/go-course/go12/skills/rpc/service"
)

func main() {
	// net/rpc
	// 1. 编写一个符合rpc框架的对象
	// 2. 怎么通过rpc框架暴露该对象, 提供rpc调用

	// 1. 注册被托管的rpc对象
	// HelloService.Hello
	err := rpc.RegisterName("HelloService", &HelloServiceImpl{})
	if err != nil {
		panic(err)
	}

	// 2. 提供网络服务(rpc框架集成)
	// 然后我们建立一个唯一的TCP链接，
	listener, err := net.Listen("tcp", ":1234")
	if err != nil {
		log.Fatal("ListenTCP error:", err)
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Fatal("Accept error:", err)
		}

		// conn --> a client ---> hello service
		// rpc 封装的网络调用

		go rpc.ServeConn(conn)
	}

}

var (
	// 显示约束
	_ service.HelloService = (*HelloServiceImpl)(nil)
)

// 进程内调用 HelloService{}.Hello()
// 符合HelloService接口约束
type HelloServiceImpl struct {
}

// 需要暴露的方法符合 net/rpc框架约束(类似于http.Handler)
// Fn(Request any, Response *any) error
func (s *HelloServiceImpl) Hello(
	in *service.HelloRequest,
	out *service.HelloResponse) error {
	// req client远程调用时的参数
	// resp 返回给客户端的响应
	out.Message = fmt.Sprintf("hello, %s", in.Name)
	return nil
}
